package sdk.pay;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Base64;
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import sdk.pay.constant.PayConfigure;
import sdk.pay.constant.PayConstant;
import sdk.pay.constant.PayExceptionType;
import sdk.pay.helper.PayAssistant;
import sdk.pay.listener.PayGetPayStatusListener;
import sdk.pay.listener.PayGetPayTypeListener;
import sdk.pay.listener.PayUtilCallBack;
import sdk.pay.model.PayTypeModel;
import sdk.pay.model.TokenParam;
import sdk.pay.utils.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import static sdk.pay.constant.PayConfigure.PAY_URL_PAY;
import static sdk.pay.constant.PayExternalConstant.*;
import static sdk.pay.listener.PayGetPayStatusListener.ERROR;

final class PayHelperIml extends PayHelper {
    /**
     * @param activity          call sdk  activity
     * @param appId             user appId
     * @param key               user aes key
     * @param vector            user aes vector
     * @param callback          user get pay type list interface
     * @param payStatusCallBack boolean if need pay result callback
     */
    PayHelperIml(Activity activity, String appId, String key, String vector,
                 PayUtilCallBack callback, boolean payStatusCallBack) {
        super(activity, callback, payStatusCallBack);
        PayLogUtil.logBase(PayConstant.VERSION_LOG);
        mHandlerThread = new HandlerThread(PayHelperIml.class.getSimpleName());
        mHandlerThread.start();
        mPayHandler = new PayHandler(mHandlerThread.getLooper());
        if (TextUtils.isEmpty(appId) || TextUtils.isEmpty(key) || TextUtils.isEmpty(vector)) {
            return;
        }
        setPayParam(appId, key, vector);
    }

    /**
     * interface for for external call，  setPayParam
     *
     * @param payParam Business information  as Sting[]
     */
    @Override
    public void setPayParam(String... payParam) {
        boolean validInitParams = checkInitParams(payParam);
        if (!validInitParams) {
            return;
        }
        setValidInitParams(true);
        mPayInfo.setPayParam(payParam);
        String systemName = mPayInfo.getPaySystemId();
        PayLogUtil.logSecond("setPayParam systemName = " + systemName);
        setSystemDefaultUrl();
    }

    /**
     * interface for for external call get pay type list
     *
     * @param tokenParam         TokenParam model
     * @param getPayTypeListener callback interface
     */
    @Override
    public void getPayType(TokenParam tokenParam, PayGetPayTypeListener getPayTypeListener) {
        if (tokenParam == null) {
            PayLogUtil.logFirst("getToken tokenParam is null");
            showToast(PayExceptionType.DATA_EXCEPTION.getMessage());
            return;
        }
        mTokenParam = tokenParam;
        mGetPayTypeListener = getPayTypeListener;
        mPayHandler.sendEmptyMessage(DO_GET_PAY_TYPE);
    }

    /**
     * public method for external call ，get PayType list model
     *
     * @return list model PayTypeModel
     */
    @Override
    public List<PayTypeModel> getPayTypeModels() {
        return mPayInfo.getPayTypeModels();
    }

    /**
     * public method for external call
     *
     * @param typeId     pay type  ZFB WX JD QQ
     * @param tokenParam the model TokenParam
     */
    @Override
    public void pay(String typeId, TokenParam tokenParam) {
        if (tokenParam == null) {
            PayLogUtil.logFirst("getToken tokenParam is null");
            showToast(PayExceptionType.DATA_EXCEPTION.getMessage());
            return;
        }
        PayAssistant.reset();
        mTokenParam = tokenParam;
        mTokenParam.setP7_productCode(typeId);
        mPayInfo.setPayTypeId(typeId);
        if (!TextUtils.isEmpty(typeId) && checkPayTypes(typeId)) {
            sendEmptyMessage(DO_STEP_PAY);
        }
    }

    /**
     * public method for external call
     *
     * @param getPayStatusListener interface for pay result
     */
    @Override
    public void getPayStatus(PayGetPayStatusListener getPayStatusListener) {
        mGetPayStatusListener = getPayStatusListener;
        sendEmptyMessage(DO_GET_PAY_STATUS);
    }

    /**
     * @param doTag doStep or doGetType
     * @return result
     */
    private boolean configServices(String doTag) {
        JSONArray servers;
        JSONArray orderServers;
        try {
            String paySdkMsg = getEncodePaySdkMsg();
            JSONObject msgObject = getDecodePaySdkMsg(paySdkMsg);
            if (msgObject != null) {
                servers = msgObject.getJSONArray("apiServices");
                orderServers = msgObject.getJSONArray("orderServices");
            } else {
                mPayURLSPUtil.clearAllServerUrl();
                return false;
            }
            if (servers != null && orderServers != null) {
                SharedPreferences.Editor editor = mPayURLSPUtil.mSharedPreferences.edit();
                editor.putInt(PayConstant.SHAREPERFERENCE_SERVCERS_SUM_KEY, servers.length());
                int current = mPayURLSPUtil.mSharedPreferences.getInt(
                        PayConstant.SHAREPERFERENCE_SERVCERS_CURRENT_KEY, 0);
                String api = (String) servers.get(current);
                PayConfigure.setAPIs(api);
                editor.putInt(PayConstant.SHAREPERFERENCE_SERVCERS_CURRENT_KEY, current);
                editor.putInt(PayConstant.SHAREPERFERENCE_ORDERSERVERS_SUM_KEY, orderServers.length());
                int current1 = mPayURLSPUtil.mSharedPreferences.getInt(
                        PayConstant.SHAREPERFERENCE_ORDERSERVERS_CURRENT_KEY, 0);
                PayConfigure.setOrderApi((String) orderServers.get(current1));
                editor.putInt(PayConstant.SHAREPERFERENCE_ORDERSERVERS_CURRENT_KEY, current1);
                editor.apply();
                return true;
            } else {
                PayLogUtil.logFifth(doTag + " servers = null");
                return false;
            }
        } catch (JSONException e) {
            e.printStackTrace();
            PayLogUtil.logFourth(doTag + " JSONParse failure = " + e.getMessage());
            showToast(PayExceptionType.DATA_EXCEPTION.getMessage());
            PayExceptionUtil.getInstance().saveExceptionFile(doTag +
                    " JSONParse failure = " + e.getMessage());
        }
        return false;
    }

    /**
     * @param type DO_GET_PAY_TYPE or DO_GET_PAY_PARAM
     */
    @Override
    protected void doGetServices(int type) {
        PayLogUtil.logFifth("doGetServices start");
        JSONObject object = new JSONObject();
        try {
            object.put("sysFlag", mPayInfo.getPaySystemId().toUpperCase());
        } catch (JSONException e) {
            e.printStackTrace();
            PayLogUtil.logFourth("doGetServices JSONException = " + e.getMessage());
            showToast(PayExceptionType.DATA_EXCEPTION.getMessage());
            PayExceptionUtil.getInstance().saveExceptionFile(
                    "doGetServices JSONException = " + e.getMessage());
        }
        byte[] encode = PayAESUtil.encrypt(object.toString(), mPayInfo.getKeyAES(), mPayInfo.getVectorAES());
        if (null == encode) {
            showToast(PayExceptionType.ENCRYPT_EXCEPTION.getMessage());
        }
        String dest = Base64.encodeToString(encode, Base64.DEFAULT);
        String str = dest.replace("+", "-")
                .replace("/", "_")
                .replace("=", "~")
                .replace("\r", "")
                .replace("\n", "");
        String url = getServicesUrl(mPayInfo.getPaySystemId()) + "/" + mPayInfo.getAppId() + "/" + str;
        getServices(type, url);
    }

    /**
     * @param systemName system platform Name
     * @return url string
     */
    private String getServicesUrl(String systemName) {
        systemName = systemName.toLowerCase();
        return systemName.equals("jft") ? PayConstant.GET_SERVICES_JFT
                : systemName.equals("cft") ? PayConstant.GET_SERVICES_CFT
                : systemName.equals("jftcs") ? PayConstant.GET_SERVICES_CS
                : systemName.equals("cftcs") ? PayConstant.GET_SERVICES_CFTCS
                : systemName.equals("yft") ? PayConstant.GET_SERVICES_YFT
                : systemName.equals("jftzl") ? PayConstant.GET_SERVICES_JFT_ZL
                : systemName.equals("wsf") ? PayConstant.GET_SERVICES_WSF
                : systemName.equals("jftzlcs") ? PayConstant.GET_SERVICES_JFT_ZL_CS
                : null;

    }

    /**
     * http getServices
     *
     * @param type DO_GET_PAY_TYPE or DO_GET_PAY_PARAM
     * @param url  http api getServices address
     */
    @Override
    protected void getServices(final int type, String url) {
        getCall(getServices, url, new PayCallback() {
            @Override
            public void onFailure() {
                getServicesFailure(type);
            }

            @Override
            public void onSuccess(Call call, Response response) {
                String result;
                try {
                    if (null != response.body()) {
                        result = response.body().string();
                        PayLogUtil.logBase("getServices onResponse result = " + result);
                        if (response.isSuccessful()) {
                            JSONObject jsonObject = new JSONObject(result);
                            String flag = jsonObject.getString("flag");
                            if (flag.equals(TASK_SUCCESS)) {
                                PayLogUtil.logFifth("getServices onResponse Success");
                                String msg = jsonObject.getString("msg");
                                mPayURLSPUtil.clearAllServerUrl();
                                SharedPreferences.Editor editor = mPayURLSPUtil.mSharedPreferences.edit();
                                editor.putString(PayConstant.SHAREPERFERENCE_MSG_KEY, msg);
                                editor.apply();
                                getServicesFinal(type);
                            } else {
                                showToast(PayExceptionType.RETURN_ERROR_DATA.getMessage());
                            }
                        } else {
                            getServicesFailure(type);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    PayLogUtil.logFourth("getServices onResponse Exception = " + e.getMessage());
                    getServicesFailure(type);
                    PayExceptionUtil.getInstance().saveExceptionFile("getServices onResponse Exception = " + e.getMessage());
                }
            }
        });
    }

    /**
     * when get services fail do
     *
     * @param type DO_GET_PAY_TYPE or DO_GET_PAY_PARAM
     */
    @Override
    protected void getServicesFailure(int type) {
        PayConfigure.setAPIs(PayConfigure.DEFAULT_PAY_URL);
        PayConfigure.setOrderApi(PayConfigure.DEFAULT_ORDER_URL);
        getServicesFinal(type);
    }

    /**
     * getServicesFinal set sdk api and then need do
     *
     * @param type DO_GET_PAY_TYPE or DO_GET_PAY_PARAM
     */
    private void getServicesFinal(int type) {
        switch (type) {
            case DO_GET_PAY_TYPE:
                sendEmptyMessage(DO_GET_PAY_TYPE);
                break;
            case DO_GET_PAY_PARAM:
                sendEmptyMessage(DO_STEP_PAY);
                break;
        }
    }

    /**
     * one step pay
     */
    @Override
    protected void doStep() {
        if (PayConfigure.isApiSetUp() || configServices("doStep")) {
            doGetParams();
        } else {
            doGetServices(DO_GET_PAY_PARAM);
        }
    }

    /**
     * getServicesIfNeeded
     * get pay type or do get pay param
     */
    @Override
    void getServicesIfNeeded() {
        if (getEncodePaySdkMsg() != null) {
            doGetServices(DO_GET_PAY_SERVICES);
        }
    }

    /**
     * encode servers list encoded data
     *
     * @return string
     */
    private String getEncodePaySdkMsg() {
        return mPayURLSPUtil.mSharedPreferences.
                getString(PayConstant.SHAREPERFERENCE_MSG_KEY, null);
    }

    /**
     * decode servers list encoded data
     *
     * @param paySdkMsg source data
     * @return JSONObject or null
     */
    private JSONObject getDecodePaySdkMsg(String paySdkMsg) {
        try {
            if (!TextUtils.isEmpty(paySdkMsg)) {
                paySdkMsg = paySdkMsg.replace("-", "+").
                        replace("_", "/").replace("~", "=");
                byte[] decryptFrom = Base64.decode(paySdkMsg, Base64.DEFAULT);
                byte[] decryptResult = PayAESUtil.decrypt(decryptFrom, mPayInfo.getKeyAES(),
                        mPayInfo.getVectorAES());
                if (decryptResult == null) {
                    PayLogUtil.logBase("decrypt Exception,now delete and try again");
                    return null;
                }
                String str = new String(decryptResult, "UTF-8");
                if (isJson(str)) {
                    return new JSONObject(str);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * doGetPayType
     */
    @Override
    protected void doGetPayType() {
        if (!PayNetUtil.isNetworkAvailable(mActivity)) {
            PayLogUtil.logFifth("getType network not available");
            showToast(PayExceptionType.NET_WORK_NOT_AVAILABLE.getMessage());
            return;
        }
        if (PayConfigure.isApiSetUp() || configServices("doGetType")) {
            PayLogUtil.logFifth("doGetPayType start");
            String plainParam = "/" + mPayInfo.getAppId() + "/";
            JSONObject object = composeTokenJson();
            if (object == null) {
                return;
            }
            String info = object.toString().replace("\\/", "/");
            PayLogUtil.logBase("GetPayType object = " + info);
            // TODO: 2017/8/1   加密可能需要修改
            String paramInfo = encryptAES(getPayTypes, info);
            String url = PayConfigure.PAY_URL_TYPE + plainParam + paramInfo;
            getPayTypes(url);
        } else {
            doGetServices(DO_GET_PAY_TYPE);
        }
    }

    /**
     * get mTokenParam model values
     *
     * @return JSONObject
     */
    private JSONObject composeTokenJson() {
        try {
            return mTokenParam.getTokenParams();
        } catch (JSONException e) {
            PayLogUtil.logFourth("composeTokenJson JSONException = " + e.getMessage());
            showToast(PayExceptionType.DATA_EXCEPTION.getMessage());
            e.printStackTrace();
            PayExceptionUtil.getInstance().saveExceptionFile("composeTokenJson JSONException = " + e.getMessage());
            return null;
        }
    }

    /**
     * set System Default Url api & order service
     */
    private void setSystemDefaultUrl() {
        String systemName = mPayInfo.getPaySystemId().toLowerCase();
        PayConfigure.DEFAULT_PAY_URL = systemName.equals("jft") ? PayConstant.DEFAULT_API_URL_JFT
                : systemName.equals("cft") ? PayConstant.DEFAULT_API_URL_CFT
                : systemName.equals("jftcs") ? PayConstant.DEFAULT_API_URL_CS
                : systemName.equals("cftcs") ? PayConstant.DEFAULT_API_URL_CFTCS
                : systemName.equals("yft") ? PayConstant.DEFAULT_API_URL_YFT
                : systemName.equals("jftzl") ? PayConstant.DEFAULT_API_URL_JFT_ZL
                : systemName.equals("wsf") ? PayConstant.DEFAULT_API_URL_WSF
                : systemName.equals("jftzlcs") ? PayConstant.DEFAULT_API_URL_JFT_ZL_CS
                : null;
        PayConfigure.DEFAULT_ORDER_URL = systemName.equals("jft") ? PayConstant.DEFAULT_PAY_URL_JFT
                : systemName.equals("cft") ? PayConstant.DEFAULT_PAY_URL_CFT
                : systemName.equals("jftcs") ? PayConstant.DEFAULT_PAY_URL_CS
                : systemName.equals("cftcs") ? PayConstant.DEFAULT_PAY_URL_CFTCS
                : systemName.equals("yft") ? PayConstant.DEFAULT_PAY_URL_YFT
                : systemName.equals("jftzl") ? PayConstant.DEFAULT_PAY_URL_JFT_ZL
                : systemName.equals("wsf") ? PayConstant.DEFAULT_PAY_URL_WSF
                : systemName.equals("jftzlcs") ? PayConstant.DEFAULT_PAY_URL_JFT_ZL_CS
                : null;
    }

    /**
     * @param url http api getPayTypes address
     */
    @Override
    protected void getPayTypes(String url) {
        getCall(getPayTypes, url, new PayCallback() {
            @Override
            public void onFailure() {
                showToast(PayExceptionType.GET_PAY_METHOD_FAILED.getMessage());
                getServicesIfNeeded();
            }

            @Override
            public void onSuccess(Call call, Response response) throws IOException {
                if (null != response.body()) {
                    String result = response.body().string();
                    PayLogUtil.logBase("getPayTypes onResponse result = " + result);
                    if (response.isSuccessful()) {
                        try {
                            JSONObject jsonObject = new JSONObject(result);
                            if (jsonObject.getString("flag").equals(TASK_SUCCESS)) {
                                ArrayList<PayTypeModel> payTypeModels = new ArrayList<>();
                                final String msg = decryptAES(getPayTypes, jsonObject.getString("msg"));
                                if (TextUtils.isEmpty(msg)) {
                                    return;
                                }
                                PayLogUtil.logBase("getPayTypes decrypt info = " + msg);
                                if (isJsonArray(msg)) {
                                    JSONArray jsonArray = new JSONArray(msg);
                                    for (int i = 0; i < jsonArray.length(); i++) {
                                        JSONObject jsonObjectItem = jsonArray.getJSONObject(i);
                                        String typeId = jsonObjectItem.getString("productTypeCode");
                                        if (typeId.startsWith(TYPE_WECHAT)) {
                                            typeId = TYPE_WECHAT;
                                        } else if (typeId.startsWith(TYPE_ALIPAY)) {
                                            typeId = TYPE_ALIPAY;
                                        } else if (typeId.startsWith(TYPE_QQPAY)) {
                                            typeId = TYPE_QQPAY;
                                        } else if (typeId.startsWith(TYPE_JDPAY)) {
                                            typeId = TYPE_JDPAY;
                                        }else if (typeId.startsWith(TYPE_YSFPAY)) {
                                            typeId = TYPE_YSFPAY;
                                        }
                                        payTypeModels.add(new PayTypeModel(jsonObjectItem.getString("payTypeName"),
                                                typeId, jsonObjectItem.getString("remark")));
                                    }
                                    mPayInfo.setPayTypeModels(payTypeModels);
                                    sendEmptyMessage(DO_SHOW_PAY_TYPE);
                                } else {
                                    showToast(PayExceptionType.DEFAULT_ERROR.getMessage());
                                    mActivity.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            PayToastUtil.showMessage(mActivity, msg);
                                        }
                                    });
                                }
                            } else {
                                PayLogUtil.logThird("getPayTypes onResponse response = " + jsonObject.toString());
                                final String msg = jsonObject.getString("msg");
                                if (msg.contains("非法交易")) {
                                    showToast(PayExceptionType.DEFAULT_ERROR.getMessage());
                                    mActivity.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            PayToastUtil.showMessage(mActivity, msg);
                                        }
                                    });
                                } else {
                                    showToast(PayExceptionType.GET_PAY_METHOD_FAILED.getMessage());
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            PayLogUtil.logFourth("getPayTypes onResponse exception = " + e.getMessage());
                            showToast(PayExceptionType.RETURN_ERROR_DATA.getMessage());
                            getServicesIfNeeded();
                            PayExceptionUtil.getInstance().saveExceptionFile("getPayTypes onResponse exception = " + e.getMessage());
                        }
                    } else {
                        showToast(PayExceptionType.SERVER_CONNECTION_EXCEPTION.getMessage());
                        getServicesIfNeeded();
                    }
                } else {
                    showToast(PayExceptionType.SERVER_CONNECTION_EXCEPTION.getMessage());
                    getServicesIfNeeded();
                }
            }
        });
    }

    /**
     * get pay param
     */
    @Override
    protected void doGetParams() {
        FormBody.Builder builder = new FormBody.Builder();
        builder.add("p1_yingyongnum", mTokenParam.getP1_appid());
        builder.add("p2_ordernumber", mTokenParam.getP2_orderNumber());
        builder.add("p3_money", mTokenParam.getP3_money());
        builder.add("p6_ordertime", mTokenParam.getP6_orderTime());
        builder.add("p7_productcode", mTokenParam.getP7_productCode());
        builder.add("p8_sign", mTokenParam.getP8_sign());
        builder.add("p9_signtype", mTokenParam.getP9_signType());
        builder.add("p14_customname", mTokenParam.getP14_customName());
        builder.add("p22_sdkversion", mTokenParam.getP22_sdkVersion());
        builder.add("p25_terminal", mTokenParam.getP25_terminal());
        builder.add("packageName", mActivity.getPackageName());
        if (!TextUtils.isEmpty(mTokenParam.getP10_bankCardCode()))
            builder.add("p10_bank_card_code", mTokenParam.getP10_bankCardCode());
        if (!TextUtils.isEmpty(mTokenParam.getP11_cardType()))
            builder.add("p11_cardtype", mTokenParam.getP11_cardType());
        if (!TextUtils.isEmpty(mTokenParam.getP12_channel()))
            builder.add("p12_channel", mTokenParam.getP12_channel());
        if (!TextUtils.isEmpty(mTokenParam.getP13_orderFailerTime()))
            builder.add("p13_orderfailertime", mTokenParam.getP13_orderFailerTime());
        if (!TextUtils.isEmpty(mTokenParam.getP15_customcontact()))
            builder.add("p15_customcontact", mTokenParam.getP15_customcontact());
        if (!TextUtils.isEmpty(mTokenParam.getP16_customip()))
            builder.add("p16_customip", mTokenParam.getP16_customip());
        if (!TextUtils.isEmpty(mTokenParam.getP17_product()))
            builder.add("p17_product", mTokenParam.getP17_product());
        if (!TextUtils.isEmpty(mTokenParam.getP18_productCat()))
            builder.add("p18_productcat", mTokenParam.getP18_productCat());
        if (!TextUtils.isEmpty(mTokenParam.getP19_productNum()))
            builder.add("p19_productnum", mTokenParam.getP19_productNum());
        if (!TextUtils.isEmpty(mTokenParam.getP20_pdesc()))
            builder.add("p20_pdesc", mTokenParam.getP20_pdesc());
        if (!TextUtils.isEmpty(mTokenParam.getP21_version()))
            builder.add("p21_version", mTokenParam.getP21_version());
        if (!TextUtils.isEmpty(mTokenParam.getP23_charset()))
            builder.add("p23_charset", mTokenParam.getP23_charset());
        if (!TextUtils.isEmpty(mTokenParam.getP24_remark()))
            builder.add("p24_remark", mTokenParam.getP24_remark());
        FormBody build = builder.build();
        postCall(PAY_URL_PAY, build, new PayCallback() {
            @Override
            public void onFailure() {
                showToast(PayExceptionType.GET_PAY_PARAM_FAILED.getMessage());
                getServicesIfNeeded();
            }

            @Override
            public void onSuccess(Call call, Response response) throws IOException {
                if (null != response.body()) {
                    String result = response.body().string();
                    PayLogUtil.logBase("getPayParam onResponse result = " + result);
                    if (response.isSuccessful()) {
                        try {
                            JSONObject jsonObject = new JSONObject(result);
                            String state = jsonObject.getString("state");
                            if (TASK_SUCCESS.equals(state)) {
                                final String paramInfo = jsonObject.getString("msg");
                                if (TextUtils.isEmpty(paramInfo)) {
                                    showToast(PayExceptionType.RETURN_ERROR_DATA.getMessage());
                                    PayLogUtil.logBase("msg is null");
                                    return;
                                }
                                if (isJson(paramInfo)) {
                                    JSONObject object = new JSONObject(paramInfo);
                                    JSONObject info = object.getJSONObject("info");
                                    setPayParams(info);
                                    sendEmptyMessage(DO_PAY);
                                } else {
                                    showToast(PayExceptionType.RETURN_ERROR_DATA.getMessage());
                                }
                            } else {
                                String temp = jsonObject.getString("msg");
                                if (!TextUtils.isEmpty(temp)) {
                                    temp = temp.replace("*", "a").replace("&", "i");
                                    String msg = new String(Base64.decode(temp.getBytes(), Base64.DEFAULT));
                                    PayLogUtil.logBase("doGetParams state = " + state + " msg = " + msg);
                                    showToast(state);
                                } else {
                                    showToast(PayExceptionType.RETURN_ERROR_DATA.getMessage());
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            PayLogUtil.logFourth("getPayParams onResponse exception = " + e.getMessage());
                            showToast(PayExceptionType.RETURN_ERROR_DATA.getMessage());
                            getServicesIfNeeded();
                            PayExceptionUtil.getInstance().saveExceptionFile("getPayParams onResponse exception = " + e.getMessage());
                        }
                    } else {
                        showToast(PayExceptionType.SERVER_CONNECTION_EXCEPTION.getMessage());
                        getServicesIfNeeded();
                    }
                } else {
                    showToast(PayExceptionType.SERVER_CONNECTION_EXCEPTION.getMessage());
                    getServicesIfNeeded();
                }
            }
        });
    }

    private void setPayParams(JSONObject jsonObject) throws JSONException {
        mPayInfo.setOrder_channelcode(jsonObject.getString("order_channelcode"));
        mPayInfo.setCallType(jsonObject.getInt("callType"));
        mPayInfo.setMethod(jsonObject.getString("method"));
        mPayInfo.setUrl(jsonObject.getString("url"));
        mPayInfo.setUserAgent(jsonObject.getString("userAgent"));
        mPayInfo.setPostData(jsonObject.getString("postData"));
        mPayInfo.setOrderId(jsonObject.getString("orderId"));
        if (null != jsonObject.opt("action")) {
            mPayInfo.setAction(jsonObject.getString("action"));
        }
    }

    private boolean checkPayTypes(String typeId) {
        if (typeId.startsWith(TYPE_WECHAT) && !PayPackageUtil.isWeChatAvailable(mActivity)) {
            PayLogUtil.logFifth("getPayParam Find Not WeChat");
            showToast(PayExceptionType.WECHAT_NOT_AVAILABLE.getMessage());
            return false;
        }
        if (typeId.startsWith(TYPE_ALIPAY) && !PayPackageUtil.isAlipayAvailable(mActivity)) {
            PayLogUtil.logFifth("getPayParam Find Not AliPay");
            showToast(PayExceptionType.ALIPAY_NOT_AVAILABLE.getMessage());
            return false;
        }
        if (typeId.startsWith(TYPE_QQPAY) && !PayPackageUtil.isQQpayAvailable(mActivity)) {
            PayLogUtil.logFifth("getPayParam Find Not QQPay");
            showToast(PayExceptionType.QQPAY_NOT_AVAILABLE.getMessage());
            return false;
        }
        return true;
    }

    private void junPayDo() {
        String url = mPayInfo.getUrl();
        if (TextUtils.isEmpty(url)) {
            showToast(PayExceptionType.PAY_ERROR.getMessage());
            return;
        }
        PayExcessiveActivity.startActivityForResult(mActivity, this,
                mPayInfo, mPayWebView, mPayStatusCallBack);
    }

    private void doPayStatus() {
        if (mPayInfo.getIsPaying() && mPayStatusCallBack) {
            PayLogUtil.logFifth("doPayStatus start");
            if (TextUtils.isEmpty(mPayInfo.getOrderId())) {
                return;
            }
            byte[] encode = PayAESUtil.encrypt(mPayInfo.getOrderId(), null, null);
            if (null == encode) {
                showToast(PayExceptionType.ENCRYPT_EXCEPTION.getMessage());
            }
            String dest = Base64.encodeToString(encode, Base64.DEFAULT);
            String str = dest.replace("+", "-").replace("/", "_").replace("=", "~").replace("\r", "").replace("\n", "");
            String url = PayConfigure.ORDER_QUERY + "/" + str;
            PayLogUtil.logBase("doPayStatus url = " + url);
            getPayStatus(url);
        }
    }

    @Override
    protected void getPayStatus(String url) {
        getCall(getPayStatus, url, new PayCallback() {
            @Override
            public void onFailure() {
                showStatus(ERROR);
                showToast(PayExceptionType.GET_PAY_STATUS_FAILED.getMessage());
            }

            @Override
            public void onSuccess(Call call, Response response) throws IOException {
                if (null != response.body()) {
                    String result = response.body().string();
                    PayLogUtil.logBase("getPayStatus onResponse result = " + result);
                    if (response.isSuccessful()) {
                        try {
                            String string = result.replace("-", "+").replace("_", "/").replace("~", "=").replace("", "\r").replace("", "\r");
                            byte[] decryptFrom = Base64.decode(string, Base64.DEFAULT);
                            byte[] decryptResult = PayAESUtil.decrypt(decryptFrom, null, null);
                            if (decryptResult == null) {
                                showToast(PayExceptionType.DECRYPT_EXCEPTION.getMessage());
                                return;
                            }
                            String str = new String(decryptResult, "UTF-8");
                            JSONObject jsonObject = new JSONObject(str);
                            String flag = jsonObject.getString("flag");
                            String msg = jsonObject.getString("msg");
                            PayLogUtil.logFirst("flag = " + flag + " msg = " + msg);
                            showStatus(Integer.parseInt(flag));
                            if (flag.equals("1")) {
                                PayLogUtil.logFourth("getPayStatus onResponse success");
                            } else {
                                PayLogUtil.logFifth("getPayStatus onResponse failure");
                                PayLogUtil.logFourth("getPayStatus onResponse failure response = " + msg);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            PayLogUtil.logFourth("getPayStatus onResponse failure with error = " + e.getMessage());
                            showStatus(ERROR);
                            showToast(PayExceptionType.RETURN_ERROR_DATA.getMessage());
                            PayExceptionUtil.getInstance().saveExceptionFile("getPayStatus onResponse failure with error = " + e.getMessage());
                        }
                    } else {
                        showStatus(ERROR);
                        showToast(PayExceptionType.SERVER_CONNECTION_EXCEPTION.getMessage());
                    }
                } else {
                    showStatus(ERROR);
                    showToast(PayExceptionType.SERVER_CONNECTION_EXCEPTION.getMessage());
                }
            }
        });
    }

    private class PayHandler extends Handler {
        PayHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            int what = msg.what;
            switch (what) {
                case DO_GET_PAY_TYPE:
                    doGetPayType();
                    break;
                case DO_GET_PAY_PARAM:
                    doGetParams();
                    break;
                case DO_PAY:
                    junPayDo();
                    break;
                case DO_SHOW_PAY_TYPE:
                    showPayTypeList();
                    break;
                case DO_GET_PAY_STATUS:
                    doPayStatus();
                    break;
                case DO_STEP_PAY:
                    doStep();
                    break;
                default:
                    break;
            }
        }
    }

}